import time
from urllib.parse import urlencode

import requests
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium import webdriver
import sys
import libs.config as data
from libs import config
from libs.log import Log
from libs.window_gpm import GpmWindow


class AdsWindow:
    def __init__(self, ads_id):
        self.api_host = 'http://127.0.0.1:50325'
        self.ads_id = str(ads_id)
        self.log = Log(self.ads_id)

    def update_window(self, proxy_config=None):
        update_url = f"{self.api_host}/api/v1/user/update"
        self.log.debug_start('update_window...')
        user_id = self.ads_id
        if str(self.ads_id).isdigit():
            accounts = data.get_accounts()
            user_id = accounts.get(str(self.ads_id)).get('user_id')
        max_try_times = 3
        try:
            # 固定窗口尺寸
            payload = {
                "user_id": user_id,
                "fingerprint_config": {
                    "screen_resolution": "920_1100",
                }
            }
            if proxy_config is not None:
                payload['name'] = f"{proxy_config['proxy_host']}:{proxy_config['proxy_port']}"
                payload['user_proxy_config'] = proxy_config
            headers = {
                'Content-Type': 'application/json'
            }
            resp = requests.request("POST", update_url, headers=headers, json=payload).json()
            self.log.debug_end('done')
        except ConnectionError:
            if ++max_try_times < 3:
                self.update_window()
            self.log.debug_end('fail')

    def open(self, close_before_open=True, offset_x=0, offset_y=0, headless=False):
        user_id = config.get_account(self.ads_id).get('user_id', '')
        if len(user_id) > 10:
            return GpmWindow(self.ads_id).open(close_before_open, offset_x=offset_x, offset_y=offset_y)

        if close_before_open:
            self.close()
            time.sleep(2)

        self.update_window()
        time.sleep(1)

        open_resp = self.open_window(headless)
        if open_resp["code"] != 0:
            print(open_resp["msg"])
            print("please check ads_id")
            sys.exit()
        web_driver = open_resp["data"]["webdriver"]
        is_chrome = True
        if is_chrome:
            service = ChromeService(executable_path=web_driver)
            chrome_options = ChromeOptions()
            chrome_options.add_experimental_option("debuggerAddress", open_resp["data"]["ws"]["selenium"])
            return webdriver.Chrome(service=service, options=chrome_options)
        else:
            port = open_resp["data"]["marionette_port"]
            # driver 实际路径
            firefox_services = FirefoxService(executable_path=web_driver,
                                              service_args=['--marionette-port', port, '--connect-existing'])
            return webdriver.Firefox(service=firefox_services)

    def open_window(self, headless=False):
        user_key = 'user_id'
        if str(self.ads_id).isdigit():
            user_key = 'serial_number'
        query = {
            'open_tabs': 1,
            'ip_tab': 0,
            'launch_args': '["--disable-blink-features=UserAgentClientHint"]',
            user_key: self.ads_id
        }
        if headless:
            query['headless'] = 1
        open_url = f"{self.api_host}/api/v1/browser/start?{urlencode(query)}"
        print('open_window', end='', flush=True)
        max_try_times = 3
        try:
            print('.', end='', flush=True)
            open_resp = requests.get(open_url).json()
            print('done', flush=True)
            return open_resp
        except ConnectionError:
            if ++max_try_times < 3:
                self.open_window()
            print('fail', flush=True)

    def close(self):
        user_id = config.get_account(self.ads_id).get('user_id', '')
        if len(user_id) > 10:
            return GpmWindow(self.ads_id).close()

        user_key = 'user_id'
        if str(self.ads_id).isdigit():
            user_key = 'serial_number'
        close_url = f"{self.api_host}/api/v1/browser/stop?{user_key}={self.ads_id}"
        self.log.debug_start('close_window')
        max_try_times = 3
        try:
            self.log.debug_append()
            requests.get(close_url)
            time.sleep(1)
            self.log.debug_end('done')
        except Exception:
            if ++max_try_times < 3:
                self.close()
            self.log.debug_end('fail')